/***************************************************************************
 * Copyright (C) 2013 Dj_Skual
 *
 * This software is provided 'as-is', without any express or implied
 * warranty. In no event will the authors be held liable for any
 * damages arising from the use of this software.
 *
 * Permission is granted to anyone to use this software for any
 * purpose, including commercial applications, and to alter it and
 * redistribute it freely, subject to the following restrictions:
 *
 * 1. The origin of this software must not be misrepresented; you
 * must not claim that you wrote the original software. If you use
 * this software in a product, an acknowledgment in the product
 * documentation would be appreciated but is not required.
 *
 * 2. Altered source versions must be plainly marked as such, and
 * must not be misrepresented as being the original software.
 *
 * 3. This notice may not be removed or altered from any source
 * distribution.
 *
 * DevDatabinButtons.cpp
 *
 * for SaveGame Manager GX
 ***************************************************************************/
#include "DevDatabinButtons.hpp"
#include "DevDatabinTask.hpp"
#include "../ManageTools.h"
#include "../../Controls/Application.h"
#include "../../Menu/Explorer.h"

enum
{
	DECOMPRESS_DEV_DATABIN = 1,
	INSTALL_DEV_DATABIN,
	DELETE_DEV_DATABIN,
	COPY_DEV_DATABIN
};

DevDatabinButtons::DevDatabinButtons()
	: GuiFrame(400, 150)
{
	SetAlignment(ALIGN_CENTER | ALIGN_BOTTOM);
	SetPosition(-6, -30);
	
	actionButtons = NULL;
	
	installButtons = new ManageButtons(tr( "Install to:" ),
									   0,
									   tr( "Wii" ),
									   tr( "Emu" ),
									   tr( "Cancel" ));
	installButtons->ButtonClicked.connect(this, &DevDatabinButtons::OnInstallClick);
	
	eNandCount = 0;
	emu1 = false;
	emu2 = false;
	emu3 = false;
	for(int ewii = EWII1; ewii <= EWII3; ++ewii)
	{
		if(DeviceHandler::Instance()->IsInserted(ewii))
		{
			if(ewii == EWII1)
			{
				emu1 = true;
				eNandCount++;
			}
			else if(ewii == EWII2)
			{
				emu2 = true;
				eNandCount++;
			}
			else if(ewii == EWII3)
			{
				emu3 = true;
				eNandCount++;
			}
		}
	}
	
	emuButtons = new ManageButtons(tr( "Install to:" ),
								   0,
								   emu1 ? tr( "Emu1" ) : NULL,
								   emu2 ? tr( "Emu2" ) : NULL,
								   emu3 ? tr( "Emu3" ) : NULL,
								   tr( "Cancel" ));
	emuButtons->ButtonClicked.connect(this, &DevDatabinButtons::OnEmuClick);
	
	pathButtons = new ManageButtons(tr( "Decompress to:" ), 0, tr( "Default" ), tr( "Browsed" ), tr( "Custom" ), tr( "Cancel" ));
	pathButtons->ButtonClicked.connect(this, &DevDatabinButtons::OnPathClick);
	
	confirmButtons = new ManageButtons(tr( "Extract to:" ), 0, tr( "OK" ), tr( "Cancel" ));
	confirmButtons->ButtonClicked.connect(this, &DevDatabinButtons::OnConfirmClick);
	
	succesButtons = new ManageButtons(tr("Succesfully extracted"), 0, tr( "OK" ));
	succesButtons->ButtonClicked.connect(this, &DevDatabinButtons::OnResultClick);
	
	errorButtons = new ManageButtons(tr( "Error:" ), 0, tr( "OK" ));
	errorButtons->ButtonClicked.connect(this, &DevDatabinButtons::OnResultClick);
	
	cancelButtons = new ManageButtons(tr("Extract cancelled"), 0, tr( "OK" ));
	cancelButtons->ButtonClicked.connect(this, &DevDatabinButtons::OnResultClick);
}

DevDatabinButtons::~DevDatabinButtons()
{
	RemoveAll();

	if(actionButtons)
		delete actionButtons;
	delete installButtons;
	delete emuButtons;
	delete pathButtons;
	delete confirmButtons;
	delete succesButtons;
	delete errorButtons;
	delete cancelButtons;
}

void DevDatabinButtons::OnActionClick(ManageButtons *buttons UNUSED, int choice)
{
	action = choice;
	BlockButtons(true);
	HideButtons(actionButtons);
	
	if(action == INSTALL_DEV_DATABIN)
	{
		if(!Settings.SneekRunning && Settings.EmuBrowsers && eNandCount)
		{
			if(installed)
				ShowButtons(installButtons);
			else
			{
				installType = INSTALL_DEV_ENAND;
				
				if(eNandCount > 1)
				{
					ShowButtons(emuButtons);
				}
				else
				{
					confirmButtons->SetTitle(tr( "Install to:" ));
					
					if(emu1)
						Settings.TmpPath = Settings.EmuNandPath_1;
					else if(emu2)
						Settings.TmpPath = Settings.EmuNandPath_2;
					else if(emu3)
						Settings.TmpPath = Settings.EmuNandPath_3;
					
					Confirm();
				}
			}
		}
		else
		{
			installType = INSTALL_DEV_NAND;
			
			confirmButtons->SetTitle(tr( "Install from:" ));
			Settings.TmpPath = Settings.LastUsedPath;
			
			Confirm();
		}
	}
	else if(action == DELETE_DEV_DATABIN)
	{
		confirmButtons->SetTitle(tr( "Delete from:" ));
		Settings.TmpPath = Settings.LastUsedPath;
		
		Confirm();
	}
	else if (action == DECOMPRESS_DEV_DATABIN)
	{
		confirmButtons->SetTitle(tr( "Decompress to:" ));
		
		ShowButtons(pathButtons);
	}
	else if(action == COPY_DEV_DATABIN)
	{
		confirmButtons->SetTitle(tr( "Copy to:" ));
		
		PathBrowser *pathBrowser = new PathBrowser(Settings.LastUsedPath);
		pathBrowser->ButtonClick.connect(this, &DevDatabinButtons::OnPathBrowserButtonClick);
	}
	
}

void DevDatabinButtons::OnInstallClick(ManageButtons *buttons UNUSED, int choice)
{
	HideButtons(installButtons);
	
	if(choice == 1)
	{
		installType = INSTALL_DEV_NAND;
		
		confirmButtons->SetTitle(tr( "Install from:" ));
		Settings.TmpPath = Settings.LastUsedPath;
		
		Confirm();
	}
	else if(choice == 2)
	{
		installType = INSTALL_DEV_ENAND;
		
		if(eNandCount > 1)
		{
			ShowButtons(emuButtons);
		}
		else
		{
			confirmButtons->SetTitle(tr( "Install to:" ));
			
			if(emu1)
				Settings.TmpPath = Settings.EmuNandPath_1;
			else if(emu2)
				Settings.TmpPath = Settings.EmuNandPath_2;
			else if(emu3)
				Settings.TmpPath = Settings.EmuNandPath_3;
			
			Confirm();
		}
	}
	else
		Cancel();
}

void DevDatabinButtons::OnEmuClick(ManageButtons *buttons UNUSED, int choice)
{
	HideButtons(emuButtons);
	
	if(choice < 4)
	{
		confirmButtons->SetTitle(tr( "Install to:" ));
		Settings.TmpPath = ManageTools::GetENandPath(choice);
		
		Confirm();
	}
	else
	{
		Cancel();
	}
}

void DevDatabinButtons::OnPathClick(ManageButtons *buttons UNUSED, int choice)
{
	HideButtons(pathButtons);
	
	if(choice == 1) //! Default
	{
		Settings.TmpPath = Settings.SaveGamePath;
		
		Confirm();
	}
	else if(choice == 2) //! Browsed
	{
		Settings.TmpPath = Settings.LastUsedPath;
		
		Confirm();
	}
	else if(choice == 3) //! Custom
	{
		PathBrowser *pathBrowser = new PathBrowser(Settings.LastUsedPath);
		pathBrowser->ButtonClick.connect(this, &DevDatabinButtons::OnPathBrowserButtonClick);
	}
	else if(choice == 4) //! Cancel
	{
		Cancel();
	}
}

void DevDatabinButtons::OnPathBrowserButtonClick(PathBrowser *menu, u8 filter UNUSED, bool doneClicked, const std::string &Path)
{
	menu->SetEffect(EFFECT_FADE, -20);
	while(menu->IsAnimated())
		Application::Instance()->updateEvents();
	menu->Close();
	
	if(doneClicked)
	{
		Settings.TmpPath = Path;
		
		Confirm();
	}
	else
	{
		Cancel();
	}
}

void DevDatabinButtons::OnConfirmClick(ManageButtons *buttons UNUSED, int choice)
{
	HideButtons(confirmButtons);
	
	if(choice == 1)
	{
		DevDatabinTask * task = NULL;
		
		if(action == INSTALL_DEV_DATABIN)
		{
			if(installType == INSTALL_DEV_NAND)
				task = new DevDatabinTask(DevDatabinTask::INSTALL_DATABIN_TO_NAND);
			else
				task = new DevDatabinTask(DevDatabinTask::INSTALL_DATABIN_TO_ENAND);
		}
		else if(action == DELETE_DEV_DATABIN)
			task = new DevDatabinTask(DevDatabinTask::DELETE_DATABIN_FROM_DEV);
		else if(action == DECOMPRESS_DEV_DATABIN)
			task = new DevDatabinTask(DevDatabinTask::DECOMPRESS_DATABIN_TO_DEV);
		else if(action == COPY_DEV_DATABIN)
			task = new DevDatabinTask(DevDatabinTask::COPY_DATABIN_TO_DEV);
		
		task->End.connect(this, &DevDatabinButtons::OnTaskEnd);
	}
	else //! Cancel
	{
		Cancel();
	}
}

void DevDatabinButtons::OnTaskEnd(GuiElement * task, int result)
{
	delete task;
	
	if(result > 0)
	{
		if(action == INSTALL_DEV_DATABIN) succesButtons->SetTitle(tr( "Succesfully installed" ));
		else if (action == COPY_DEV_DATABIN) succesButtons->SetTitle(tr( "Succesfully copied" ));
		else if (action == DECOMPRESS_DEV_DATABIN) succesButtons->SetTitle(tr( "Succesfully decompressed" ));
		else if (action == DELETE_DEV_DATABIN)
		{
			deleted = true;
			succesButtons->SetTitle(tr( "Succesfully deleted" ));
		}
		
		ShowButtons(succesButtons);
	}
	else if(result == 0)
	{
		if(action == INSTALL_DEV_DATABIN) cancelButtons->SetTitle(tr( "Install cancelled" ));
		else if (action == DELETE_DEV_DATABIN) cancelButtons->SetTitle(tr( "Delete cancelled" ));
		else if (action == DECOMPRESS_DEV_DATABIN) cancelButtons->SetTitle(tr( "Decompress cancelled" ));
		else cancelButtons->SetTitle(tr( "Copy cancelled" ));
		
		ShowButtons(cancelButtons);
	}
	else if(result < 0)
	{
		if (action == DELETE_DEV_DATABIN) errorButtons->SetMessage(tr( "Unable to delete datas" ));
		else if (action == DECOMPRESS_DEV_DATABIN) errorButtons->SetMessage(tr( "Unable to decompress datas" ));
		else errorButtons->SetMessage(tr( "Unable to copy datas" ));
		
		ShowButtons(errorButtons);
	}
}

void DevDatabinButtons::OnResultClick(ManageButtons *buttons, int choice UNUSED)
{
	if((action == DELETE_DEV_DATABIN) && deleted)
		EntryDeleted();
	deleted = false;
	
	HideButtons(buttons);
	Cancel();
}

void DevDatabinButtons::Cancel()
{
	ShowButtons(actionButtons);
	
	BlockButtons(false);
}

void DevDatabinButtons::Confirm()
{
	confirmButtons->SetMessage(Settings.TmpPath);
	
	ShowButtons(confirmButtons);
}

void DevDatabinButtons::HideButtons(ManageButtons *buttons)
{
	buttons->SetEffect(EFFECT_FADE, -20);
	while(buttons->IsAnimated())
		Application::Instance()->updateEvents();
	Remove(buttons);
}

void DevDatabinButtons::ShowButtons(ManageButtons *buttons)
{
	buttons->SetEffect(EFFECT_FADE, 20);
	Append(buttons);
	while(buttons->IsAnimated())
		Application::Instance()->updateEvents();
}

void DevDatabinButtons::SetActionButtons()
{
	deleted = false;
	
	Remove(actionButtons);
	if(actionButtons)
		delete actionButtons;
	
	installed = !CurrentBrowser()->IsNotInstalled(CurrentBrowser()->GetSelIndex());
	bool display_install = false;
	if(installed || (!Settings.SneekRunning && Settings.EmuBrowsers && eNandCount))
		display_install = true;
	
	actionButtons = new ManageButtons(0,
									  0,
									  tr( "Decompress" ),
									  display_install ? tr( "Install" ) : NULL,
									  tr( "Delete" ),
									  tr( "Copy" ));
	actionButtons->SetPosition(0, installed ? 0 : -25);
	actionButtons->ButtonClicked.connect(this, &DevDatabinButtons::OnActionClick);
	
	Append(actionButtons);
}
